/*******************************************************************************
 * @note Copyright (C) 2011-2022, Shanghai Panchip Microelectronics Co., Ltd. 
 * @SPDX-License-Identifier: Apache-2.0
 * @history - V0.1, 2022-09-28
*******************************************************************************/
#include "at.h"
#include "ddl.h"
#include "hardware.h"
#include "service_pt.h"
#include "service_net.h"
#include "service_nodemode.h"

nm_proc_t nm_proc;
boolean_t setb_level;

extern node_config_t node_config;

/**
 * @brief Set the current operation mode to IO mode
 * @param null 
 * @return null
 */
void nm_set_io_op(void)
{
    /* switch workmode by io level */
    nm_proc.nodemode_op = NODE_MODE_OP_IO;
}

/**
 * @brief Set the current operation mode to AT mode
 * @param null 
 * @return null
 */
void nm_set_at_op(void)
{
    /* switch workmode by atcmd("+++") */
    nm_proc.nodemode_op = NODE_MODE_OP_AT;
}

/**
 * @brief Node enters at mode
 * @param null 
 * @return null
 */
void nm_enter_at_mode(void)
{
    /* stop and clear data process */
    if ( node_config.work_mode == WORKMODE_PT)
    {
        pt_delete();
    }
    else if ( node_config.work_mode == WORKMODE_NET )
    {
        net_clean();
    }

    /* init and run at process */
    at_server_init();
    nm_proc.state = NM_STATE_AT;
}

/**
 * @brief Node enters data mode
 * @param null 
 * @return null
 */
void nm_enter_data_mode(void)
{
    /* stop and clear at process */
    at_server_clean(); 

    /* init and run data process */
    if ( node_config.work_mode == WORKMODE_PT )
    {
        pt_init();
    }
    else if ( node_config.work_mode == WORKMODE_NET )
    {
        net_init();
    }

    nm_proc.state = NM_STATE_DATA;
}

/**
 * @brief node mode process
 * @param null 
 * @return null
 */
void nm_process(void)
{
    /* if current operation mode is by SETA */
    if ( nm_proc.nodemode_op == NODE_MODE_OP_IO )
    {
        switch ( nm_proc.state )
        {
            case NM_STATE_AT :
                /* if seta level is inactive, enter data mode */
                if ( GPIO_SETA_LEVEL_GET() == LEVEL_INACTIVE )
                {
                    /* enter data transfer mode */
                    nm_enter_data_mode();
                }
                break;
            case NM_STATE_DATA :
                if ( GPIO_SETA_LEVEL_GET() == LEVEL_ACTIVE )
                {
                    /* enter at cmd mode */
                    nm_enter_at_mode();
                }
                break;
            default:
                nm_enter_at_mode();
                break;
        }
    }

    /* Detect whether level of SETB changes */
    if ( setb_level != GPIO_SETB_LEVEL_GET() )
    {
        /* update the setb_level */
        setb_level = GPIO_SETB_LEVEL_GET();
        
        pt_io_set_evt();  /* notify pt task if level of SETB changes */
        net_io_set_evt(); /* notify net task if level of SETB changes */
    }
}

/**
 * @brief node mode initialize
 * @param null 
 * @return null
 */
void nm_init(void)
{
    /* When power on, if GPIO_SETA is LEVEL_ACTIVE, 
       Node enters at mode, otherwise enters data mode*/
    if ( GPIO_SETA_LEVEL_GET() == LEVEL_ACTIVE )
    {
        /* Node enters at mode */
        at_server_init();
        nm_proc.state = NM_STATE_AT;
    }
    else
    {   /* Node enters data mode:WORKMODE_PT or WORKMODE_NET */
        if ( node_config.work_mode == WORKMODE_PT)
        {
            pt_init();
        }
        else if ( node_config.work_mode == WORKMODE_NET )
        {
            net_init();
        }
        
        nm_proc.state = NM_STATE_DATA;
    }

    setb_level = GPIO_SETB_LEVEL_GET();
}


